perm filename PUPINT.C[11,HE] blob sn#688203 filedate 1982-12-06 generic text, type T, neo UTF8
/* LINTLIBRARY */
/*
 * pupint.c
 *
 * pupint sets an interrupt to be delivered if a packet arrives
 * on the given PupChan.
 *
 * pupnoint disables interrupts on the given PupChan.
 *
 * Very Unix-specific at this point.
 *
 * Jeffrey Mogul @ Stanford	3 April 1981
 *
 */

#include <puplib.h>
#include <signal.h>

/* global (static) table associating signals
 * with actions
 */
struct _sigtabent {	/* one per possible signal */
	void (*action)();	/* action routine to call upon signal */
	char *arg;		/* user-specifiable arg to action routine */
	struct PupChan *Pc;	/* associated Pup channel (pass to action) */
	}
	_PupSigTable[NSIG];

void _pupsigcatch();	/* forward declaration */

/*
 * pupint arranges for "routine" to be called whenever a packet
 * arrives on Pchan.  The signum argument should be a signal
 * which is unique to the given pupchan, i.e., not used elsewhere
 * in the user's program.  The call is "routine(Pchan,userarg)",
 * i.e., both the current Pup channel and the userarg are passed.
 */
pupint(Pchan,signum,routine,userarg)
struct	PupChan	*Pchan;		/* channel data structure */
int	signum;			/* signal number to set */
void	(*routine)();		/* user-specified service routine address */
char	*userarg;		/* user argument to service routine */
{
	
	if ((signum > 0) && (signum <= NSIG)) {	
		/* don't allow illegal signal numbers */
	    _PupSigTable[(signum)].action = routine;
	    _PupSigTable[(signum)].Pc = Pchan;
	    _PupSigTable[(signum)].arg = userarg;

	    sigset(signum,_pupsigcatch);	/* set up our own catcher */
		/*
		 * another place to special-case on network type
		 */
	    ensignal(Pchan->ifid,signum);	/* enable signal */
	}
}

pupnoint(Pchan)
struct	PupChan	*Pchan;		/* channel data structure */
{
	/*
	 * another place to special-case on network type
	 */
	ensignal(Pchan->ifid,0);	/* signal 0 == no signal */
}

/*
 * catcher for pup signals -- dispatch to user-specified
 * routine, then reenable signals.
 */
void _pupsigcatch(whatsig)
int whatsig;		/* signal that invoked this routine */
{	/* */
	register struct _sigtabent *stp;
	
	stp = &(_PupSigTable[whatsig]);
	
	/* call user-specified service routine */
	(*(stp->action))(stp->Pc,stp->arg);

		/*
		 * another place to special-case on network type
		 */
	ensignal(stp->Pc->ifid,whatsig);	/* reenable signal */
}